﻿///////////////////////////////////////////////////////////////////////////////
//
// This file is part of the BassDrop project
//   https://code.google.com/p/bass-drop/
//
//
// Creator:	Gergely Krajcsovszki (krajcsovszkig@hotmail.com)
// Date:	2013-08-20 12:25
//
//
// Copyright © 2013-2014. Gergely Krajcsovszki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace BassDrop.Core.Common.Data.IO.Portable
{
	/// <summary>
	/// Implementations provide various file handling and path manipulation functions
	/// that work on their platforms.
	/// </summary>
	public interface IFileHandler
	{
		/// <summary>
		/// Creates a uniquely named, zero-byte temporary file on disk and returns the full path of that file.
		/// Similar to System.IO.Path.GetTempFileName
		/// </summary>
		/// <returns>The full path of the temporary file.</returns>
		string GetTempFileName();

		/// <summary>
		/// Opens a text file, reads all lines of the file into a string, and then closes the file.
		/// Similar to System.IO.File.ReadAllText
		/// </summary>
		/// <param name="path">The file to open for reading.</param>
		/// <returns>A string containing all lines of the file.</returns>
		string ReadAllText( string path );

		/// <summary>
		/// Creates a new file, write the contents to the file, and then closes the file. If the target file already exists, it is overwritten.
		/// Similar to System.IO.File.WriteAllText
		/// </summary>
		/// <param name="path">The file to write to.</param>
		/// <param name="contents">The string to write to the file.</param>
		void WriteAllText( string path, string contents );

		/// <summary>
		/// Deletes the specified file.
		/// Similar to System.IO.File.Delete
		/// </summary>
		/// <param name="path">The name of the file to be deleted. Wildcard characters are not supported.</param>
		void Delete( string path );

		/// <summary>
		/// Returns the directory information for the specified path string.
		/// Similar to System.IO.Path.GetDirectoryName
		/// </summary>
		/// <param name="path">The path of a file or directory.</param>
		/// <returns>Directory information for path, or null if path denotes a root directory or is null. Returns String.Empty if path does not contain directory information.</returns>
		string GetDirectoryName( string path );

		/// <summary>
		/// Returns the file name and extension of the specified path string.
		/// Similar to System.IO.Path.GetFileName
		/// </summary>
		/// <param name="path">The path string from which to obtain the file name and extension.</param>
		/// <returns>
		/// The characters after the last directory character in path.
		/// If the last character of path is a directory or volume separator character, this method returns String.Empty.
		/// If path is null, this method returns null.
		/// </returns>
		string GetFileName( string path );

		/// <summary>
		/// Returns the extension of the specified path string.
		/// </summary>
		/// <param name="path">The path string from which to get the extension.</param>
		/// <returns>
		/// The extension of the specified path (including the period "."), or null, or String.Empty.
		/// If path is null, GetExtension returns null. If path does not have extension information,
		/// GetExtension returns String.Empty.
		/// </returns>
		string GetExtension( string path );

		/// <summary>
		/// Determines whether the specified file exists.
		/// Similar to System.IO.File.Exists
		/// </summary>
		/// <param name="path">The file to check.</param>
		/// <returns>
		/// true if the caller has the required permissions and path contains the name of an existing file;
		/// otherwise, false.
		/// This method also returns false if path is null, an invalid path, or a zero-length string.
		/// If the caller does not have sufficient permissions to read the specified file, no exception is
		/// thrown and the method returns false regardless of the existence of path.
		/// </returns>
		bool Exists( string path );

		/// <summary>
		/// Moves a specified file to a new location, providing the option to specify a new file name.
		/// Similar to System.IO.File.Move
		/// </summary>
		/// <param name="sourceFileName">The name of the file to move.</param>
		/// <param name="destFileName">The new path for the file.</param>
		void Move( string sourceFileName, string destFileName );

		/// <summary>
		/// Returns the list of files from a directory
		/// </summary>
		/// <param name="directoryPath"></param>
		/// <returns></returns>
		IEnumerable<string> GetFiles( string directoryPath );

		/// <summary>
		/// Returns the list of subdirectories from a directory
		/// </summary>
		/// <param name="directoryPath"></param>
		/// <returns></returns>
		IEnumerable<string> GetDirectories( string directoryPath );

		/// <summary>
		/// Returns the list of files and subdirectories from a directory
		/// </summary>
		/// <param name="directoryPath"></param>
		/// <returns></returns>
		IEnumerable<string> GetFileSystemEntries( string directoryPath );

		/// <summary>
		/// Converts the passed relative path string to a Uri
		/// </summary>
		/// <param name="relativePath"></param>
		/// <returns></returns>
		Uri ToUri( string relativePath );

		/// <summary>
		/// Opens the file on the passed URI and returns a stream to it.
		/// Similar to System.IO.File.Open
		/// </summary>
		/// <param name="path">The path to the file.</param>
		/// <param name="mode">A FileMode value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten.</param>
		/// <param name="access">A FileAccess value that specifies the operations that can be performed on the file.</param>
		/// <param name="share">A FileShare value specifying the type of access other threads have to the file.</param>
		/// <param name="createDirs">Automatically create directories for the file if needed</param>
		/// <returns>a stream to the file</returns>
		Stream GetStream( string path, PortableFileMode mode, PortableFileAccess access, PortableFileShare share, bool createDirs = true );

		/// <summary>
		/// Returns the MD5 hash of the passed file
		/// </summary>
		/// <param name="path"></param>
		/// <returns></returns>
		string GetMD5Hash( string path );

		/// <summary>
		/// Returns the path of the personal directory of the current user
		/// </summary>
		/// <returns></returns>
		string GetUserDir();

		/// <summary>
		/// Returns the metadata of the passed file
		/// </summary>
		/// <param name="path"></param>
		/// <returns></returns>
		FileMetadata GetMetadata( string path );

		/// <summary>
		/// Sets the metadata of the passed file
		/// </summary>
		/// <param name="path"></param>
		/// <param name="metadata"></param>
		/// <returns></returns>
		void SetMetadata( string path, FileMetadata metadata );
	}
}
